package com.kamistoat.meimeimall.meimeimallware.listener;

import com.kamistoat.meimeimall.common.runTimeFunc.RunTimeLog;
import com.kamistoat.meimeimall.meimeimallware.service.WareSkuService;
import com.kamistoat.meimeimall.common.To.wareTo.LockOrderWareTo;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class StockSeckillOrderListener {
    @Autowired
    WareSkuService wareSkuService;

    /**
     * 当秒杀活动成功创建订单时，会向该队列中投递库存工单。该监听器处理库存工单，去锁定真实库存。
     * 这里到底要不要操作数据库？想了之后还是操作数据库好了。
     * @param message
     * @param lockOrderWareTo 库存工单
     * @param channel
     */
    @RabbitListener(queues = "stock.seckill.stock.queue")
    public void handleSeckillNewStock(Message message, LockOrderWareTo lockOrderWareTo, Channel channel){
        RunTimeLog.printRunTimeLog("监听到新创建的未支付秒杀订单，按照订单保存库存工单并锁定库存:" + lockOrderWareTo.getOrderSn());
        // 向RabbitMQ手动进行ack
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            wareSkuService.orderLockStock(lockOrderWareTo);
            // 假如服务异常，或者手动ack时异常，都会进入catch
            // 注意第二个参数 false 不是传递false回调，是是否将之前的消息一并ack
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            RunTimeLog.printRunTimeLog("保存库存工单并锁定库存出现异常:" + lockOrderWareTo.getOrderSn());
            e.printStackTrace();
        }
    }
}
